package com.imooc.imoocbilibili.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.imooc.imoocbilibili.constants.UserConstant;
import com.imooc.imoocbilibili.entity.FollowingGroup;
import com.imooc.imoocbilibili.entity.User;
import com.imooc.imoocbilibili.entity.UserInfo;
import com.imooc.imoocbilibili.exception.RRException;
import com.imooc.imoocbilibili.interceptor.ThreadUser;
import com.imooc.imoocbilibili.service.FollowingGroupService;
import com.imooc.imoocbilibili.service.UserInfoService;
import com.imooc.imoocbilibili.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.imooc.imoocbilibili.mapper.UserFollowingMapper;
import com.imooc.imoocbilibili.entity.UserFollowing;
import com.imooc.imoocbilibili.service.UserFollowingService;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service("userFollowingService")
@RequiredArgsConstructor
public class UserFollowingServiceImpl extends ServiceImpl<UserFollowingMapper, UserFollowing> implements UserFollowingService {

    private final FollowingGroupService followingGroupService;
    private final UserService userService;
    private final UserInfoService userInfoService;

    @Override
    public Page<UserFollowing> queryPage(Integer pageNo, Integer pageSize) {
        Page<UserFollowing> page = this.page(
                new Page<>(pageNo, pageSize),
                // 拼接查询条件
                new LambdaQueryWrapper<UserFollowing>()
        );

        return page;
    }

    public void addUserFollowings(UserFollowing userFollowing) {
        Long groupid = userFollowing.getGroupid();
        if (groupid == null) {
            // 没有则使用默认分组
            FollowingGroup followingGroup = followingGroupService.getOne(new LambdaQueryWrapper<FollowingGroup>().eq(FollowingGroup::getType, UserConstant.USER_FOLLOWING_GROUP_TYPE_DEFAULT));
            userFollowing.setGroupid(followingGroup.getId());
        } else {
            FollowingGroup followingGroup = followingGroupService.getById(groupid);
            if (followingGroup == null) {
                throw new RRException("分组不存在");
            }
        }

        // 查询被关在的用户是否存在
        Long followingid = userFollowing.getFollowingid();
        User user = userService.getById(followingid);
        if (user == null) {
            throw new RRException("关注的用户不存在");
        }

        // 查询是否已经关注过了
        User currentUser = ThreadUser.getUser();
        UserFollowing following = this.getOne(new LambdaQueryWrapper<UserFollowing>()
                .eq(UserFollowing::getUserid, currentUser.getId())
                .eq(UserFollowing::getFollowingid, followingid));
        if (following != null) {
            throw new RRException("请勿重复关注");
        }

        // 新增关注
        UserFollowing userFollowingNew = new UserFollowing();
        userFollowingNew.setUserid(currentUser.getId());
        userFollowingNew.setGroupid(groupid);
        userFollowingNew.setFollowingid(followingid);
        userFollowingNew.setCreatetime(new Date());
        this.save(userFollowingNew);
    }

    @Override
    public List<FollowingGroup> getUserFollowings() {
        User user = ThreadUser.getUser();
        Long userId = user.getId();

        // 用户的所有关注
        List<UserFollowing> userFollowings = this.list(new LambdaQueryWrapper<UserFollowing>().eq(UserFollowing::getUserid, userId));
        if (CollectionUtil.isEmpty(userFollowings)) {
            return new ArrayList<>();
        }
        // 分组
        Map<Long, List<UserFollowing>> userFollowingMap = userFollowings.stream().collect(Collectors.groupingBy(UserFollowing::getGroupid));
        // 获取用户的所有关注分组
        List<FollowingGroup> followingGroups = followingGroupService.list(new LambdaQueryWrapper<FollowingGroup>()
                .and(e -> e.eq(FollowingGroup::getUserid, user)
                        .or()
                        .in(FollowingGroup::getType, Arrays.asList("0", "1", "2"))));

        // 给分组填充属性
        for (FollowingGroup followingGroup : followingGroups) {
            Long id = followingGroup.getId();
            List<UserFollowing> userFollowingList = userFollowingMap.get(id);
            // 该分组下没有关注用户
            if (CollectionUtil.isEmpty(userFollowingList)) {
                followingGroup.setFollowingUserInfoList(new ArrayList<>());
            } else {
                List<Long> followIds = userFollowingList.stream().map(UserFollowing::getFollowingid).collect(Collectors.toList());
                List<UserInfo> followUsers = userInfoService.list(new LambdaQueryWrapper<UserInfo>().in(UserInfo::getUserid, followIds));
                followingGroup.setFollowingUserInfoList(followUsers);
            }
        }
        return followingGroups;
    }

    /**
     * 1.获取当前用户的粉丝列表
     * 2.根据粉丝的用户id查询基本信息
     * 3.查询当前用户是否关注了粉丝(互粉)
     */
    public List<UserFollowing> getUserFans() {
        User user = ThreadUser.getUser();
        Long userId = user.getId();

        List<UserFollowing> fanList = this.list(new LambdaQueryWrapper<UserFollowing>()
                .eq(UserFollowing::getFollowingid, userId));

        for (UserFollowing fan : fanList) {
            Long fanUserId = fan.getUserid();
            UserInfo fanUserInfo = userInfoService.getOne(new LambdaQueryWrapper<UserInfo>().eq(UserInfo::getUserid, fanUserId));
            long count = this.count(new LambdaQueryWrapper<UserFollowing>()
                    .eq(UserFollowing::getUserid, userId).eq(UserFollowing::getFollowingid, fanUserInfo.getUserid()));
            fan.setFollowed(count > 0);
        }

        return fanList;
    }
}